package com.g17.virtualpetbackend.controller;

import com.g17.virtualpetbackend.entity.Medicine;
import com.g17.virtualpetbackend.service.MedicineService;
import com.g17.virtualpetbackend.utilty.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@RestController
public class MedicineController {
    @Autowired
    private MedicineService medicineService;

    private static final Logger LOGGER = LoggerFactory.getLogger(MedicineController.class);

    @GetMapping("/medicine")
    public List<Medicine> getMedicine(@RequestParam(value = "medicine",required = false) String medicine)
    {
        ArrayList<Medicine> medicines = new ArrayList<>();
        if (medicine==null){
            LOGGER.info("find all medicine");
            medicines.addAll(medicineService.findAllMedicine());
        }
        else{
            medicines.add(medicineService.findMedicineByName(medicine));
        }
        return medicines;
    }

    @RequestMapping(value = "/medicine/{id}", method = RequestMethod.GET)
    public Medicine getOneMedicine(@PathVariable("id") Long id) {
        return medicineService.getMedicineById(id);
    }

    @PostMapping("/medicine")
    public Response changeMedicine(@RequestParam(name = "id", required = false) Long id,
                                   @RequestParam(name = "medicine", required = false) String medicine,
                                   @RequestParam(name = "price", required = false) String price,
                                   @RequestParam(name = "function", required = false) String function){
        Medicine aMedicine;
        if (id==null){
            aMedicine = medicineService.createMedicine(medicine, price, function);
        }else{
            aMedicine = medicineService.updateMedicine(id, medicine, price, function);
        }

        if (aMedicine!=null){
            return new Response(aMedicine.getId(),Response.OK);
        }else{
            return new Response(Response.ERROR_ID,Response.ERROR);
        }
    }

    @DeleteMapping("/medicine")
    public Response deleteMedicine(@RequestParam(name = "id") Long id){
        Medicine medicine = medicineService.deleteMedicine(id);
        if (medicine!=null){
            return new Response(medicine.getId(),Response.OK);
        }else{
            return new Response(Response.ERROR_ID,Response.ERROR);
        }
    }

    @PostMapping("/subscribeMedicine")
    public Response addMedicineToUser(@RequestBody UserMedicine userMedicine){
        String username = userMedicine.getUsername();
        LOGGER.info(username);
        ArrayList<String> medicineNames = new ArrayList<>(userMedicine.getMedicine());
        LOGGER.info(Arrays.toString(medicineNames.toArray()));

        //avoid duplicate subscribe
        List<Medicine> alreadySubscribed = medicineService.findAllMedicineSubscribedByUser(username);
        for (Medicine medicine : alreadySubscribed) {
            if (medicineNames.contains(medicine.getMedicine())){
                return new Response(Response.ERROR_ID,Response.ERROR);
            }
        }

        for (String medicineName : medicineNames) {
            medicineService.assignMedicineToUser(medicineName,username);
        }

        return new Response(Response.ERROR_ID,Response.OK);
    }

    @PostMapping("/unsubscribeMedicine")
    public Response deleteMedicineToUser(@RequestParam(name = "medicine") String medicine, @RequestParam(name = "username") String username){
        ArrayList<Medicine> medicines = new ArrayList<>(medicineService.findAllMedicineSubscribedByUser(username));
        boolean exist = false;
        for (Medicine medicine1 : medicines) {
            //already linked
            if (medicine1.getMedicine().equals(medicine)){
                exist = true;
                break;
            }
        }
        if (!exist){
            return new Response(Response.ERROR_ID,Response.ERROR);
        }
        try {
            medicineService.unassignMedicineToUser(medicine, username);
        }catch (Exception e){
            e.printStackTrace();
            return new Response(Response.ERROR_ID,Response.ERROR);
        }

        return new Response(Response.ERROR_ID,Response.OK);
    }

    @GetMapping("/subscribeMedicine")
    public List<Medicine> findMedicineSubscribedByUser(@RequestParam(name = "username") String username){
        LOGGER.info(username);
        return medicineService.findAllMedicineSubscribedByUser(username);
    }

    private static class UserMedicine{
        private String username;
        private List<String> medicine;//medicine name

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public List<String> getMedicine() {
            return medicine;
        }

        public void setMedicine(List<String> medicine) {
            this.medicine = medicine;
        }
    }
}
